package com.yupi.usercenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.usercenter.common.ErrorCode;
import com.yupi.usercenter.exception.BusinessException;
import com.yupi.usercenter.service.UserService;
import com.yupi.usercenter.model.domain.User;
import com.yupi.usercenter.mapper.UserMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.yupi.usercenter.contant.UserConstant.USER_LOGIN_STATE;

/**
 * 用户服务实现类
 *
 * @author yulian
 */
@Service
//lombok提供的注解
//可以使用log(记录日志，记录问题)
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    //注入mapper, 对数据库操作
    @Resource
    private UserMapper userMapper;
    /**
     * 盐值，混淆密码
     */
    private static final String SALT = "yupi";


    @Override
    public long userRegister(String userAccount, String userPassword, String checkPassword) {
        // 1，校验
        //使用该方法可以判断多个参数是否为空，是否为null
        //planeCode可以为空，邀请码选填
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
            //参数二为描述信息
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        //账户名的长度不小于4
        if (userAccount.length() < 4) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名不能小于四位");
        }
        //密码不小于八位
        if (userPassword.length() < 8 || checkPassword.length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码不小于八位");
        }
        //账户不能包含特殊字符
        String validPattern = "[`~!@#$名^&*()+=|{}':;',\\\\[\\\\].<>/?~! @#￥$.&*()-+|{}【】';:“w\n" +
                "?]";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        //如果没有找到validPattern里面的字符(是特殊字符)
        if (matcher.find()) {
            return -1;
        }
        //判断两个字符串不能用==，要用equals进行比较
        //比较密码和校验密码
        if (!userPassword.equals(checkPassword)) {
            return -1;
        }


        //在数据库中查询是否有相同账户名的人
        //编写查询条件queryWrapper
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //查询账户名和我们的输入名相等
        queryWrapper.eq("userAccount", userAccount);
        //count()括号里是具体要从数据库查询哪些内容
        //this就是指向调用它的当前对象，即UserServiceImpl
        //将查询条件传递给方法
        long count = userMapper.selectCount(queryWrapper);
        //如果有人注册了
        if (count > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户不能重复");

        }

        //加密
        //Spring密码加密类(永远不要想着对密码进行解密)
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());

        //向数据库插入数据
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(encryptPassword);
        user.setAvatarUrl("https://foruda.gitee.com/avatar/1714887959600492555/10396122_t-ly9z_1714887959.png!avatar200");
        user.setUsername(userAccount);
        //        user.setPlaneCode(planeCode);
        //使用save方法将对象保存到数据库中
        boolean saveResult = this.save(user);
        //如果保存失败(id未获取，即是null的话就退出)
        //索引1
        if (!saveResult) {
            return -1;
        }

        //最后返回用户id
        //索引1防止了后面返回long但是是null而报错
        return user.getId();
    }

    @Override
    public User userLogin(String userAccount, String userPassword, HttpServletRequest request) {
        // 1、校验
        //使用该方法可以判断多个参数是否为空，是否为null
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            //返回空信息，表示登录失败
            return null;
        }
        //账户名的长度不小于4
        if (userAccount.length() < 4) {
            return null;
        }
        //密码不小于八位
        if (userPassword.length() < 8) {
            return null;
        }
        //账户不能包含特殊字符
        String validPattern = "[`~!@#$名^&*()+=|{}':;',\\\\[\\\\].<>/?~! @#￥$.&*()-+|{}【】';:“w\n" +
                "?]";
        Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
        //如果包含特殊字符
        if (matcher.find()) {
            return null;
        }

        //2、加密
        String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
        //查询用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //比较账号和密码
        queryWrapper.eq("userAccount", userAccount);
        queryWrapper.eq("userPassword", encryptPassword);
        //查询一条数据
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            //英文日志不容易出现乱码
            log.info("user login failed, userAccount cannot match userPassword");
            return null;
        }

        User safetyUser = getSafetyUser(user);
        //4、记录用户登录态(键值对)
        request.getSession().setAttribute(USER_LOGIN_STATE, safetyUser);

        //5、返回脱敏后的用户信息对象
        return safetyUser;
    }

    @Override
    public User getSafetyUser(User originUser) {
        //null可以使用等号连
        if (originUser == null) {
            return null;
        }
        //3、用户脱敏(安全账户,密码不返回)
        User safetyUser = new User();
        safetyUser.setId(originUser.getId());
        safetyUser.setUsername(originUser.getUsername());
        safetyUser.setUserAccount(originUser.getUserAccount());
        safetyUser.setAvatarUrl(originUser.getAvatarUrl());
        safetyUser.setGender(originUser.getGender());
        safetyUser.setPhone(originUser.getPhone());
        safetyUser.setEmail(originUser.getEmail());
        //添加邀请码的脱敏信息
//        safetyUser.setPlaneCode(originUser.getPlaneCode());
        //设置返回权限
        safetyUser.setUserRole(originUser.getUserRole());
        safetyUser.setUserStatus(originUser.getUserStatus());//用户的状态
        safetyUser.setCreateTime(originUser.getCreateTime());
        return safetyUser;
    }

    @Override
    public int userLogout(HttpServletRequest request) {
        //移除记录用户登录态的属性
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return 1;
    }
}




